#ifndef ABSTRACTITEM_H
#define ABSTRACTITEM_H


#include "models_global.h"


#include <QObject>
#include <QVariant>


#include <QSharedData>
#include <QSharedDataPointer>



class MODELSSHARED_EXPORT AbstractItem : public QObject
{
    Q_OBJECT

    class Data : public QSharedData
    {
    public:
        Data() {}
        Data(const Data& other) : QSharedData(other)
        {
            name = other.name;
            desc = other.desc;
        }

        QVariant name;
        QVariant desc;
    };

public:

    enum DataType
    {
        UndefinedData = -1,

        DataType_FIRST = 0,
        NameData = DataType_FIRST,
        IdData,

        CategoryData,

        DataType_LAST = CategoryData,

        DescData = -2
    };


    AbstractItem(QObject *parent = 0);
    virtual ~AbstractItem() {}
    AbstractItem(const AbstractItem& other) : QObject()
    {
        d = other.d;
    }

    // general data accessors
    QVariant data(const int& field, int role = Qt::DisplayRole) const;
    void setData(const int& field, const QVariant& data = QVariant());

    AbstractItem* rootItem();

    // for model
    virtual int fieldCount() const = 0;
    virtual int itemCount() const;

    virtual QList<AbstractItem*> items() const;
    virtual AbstractItem* itemAt(const int& index) const;
    virtual void removeAt(const int& index );


    // for serializer
    virtual QString fieldName(const int& field) const;
    virtual int field(const QString& name) const;


    //convenience getters
    virtual int category() const;
    virtual QString name() const;
    virtual QString desc() const;


signals:

    void sigDirty();


protected:

    virtual void setCustomData(const int& data_type, const QVariant& data) = 0;
    virtual QVariant customData(const int& data_type, int role = Qt::DisplayRole) const = 0;


private:

    QSharedDataPointer<Data> d;

    friend class AbstractItem;


};


Q_DECLARE_METATYPE(AbstractItem*);


#endif // ABSTRACTITEM_H

